package com.itqf.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itqf.bean.DtsAdmin;
import com.itqf.bean.DtsAdminExample;
import com.itqf.constants.ShiroConstants;
import com.itqf.dto.CommonsDto;
import com.itqf.mapper.DtsAdminMapper;
import com.itqf.service.DtsAdminService;
import com.itqf.service.DtsPermissionService;
import com.itqf.service.DtsRoleService;
import com.itqf.util.ResponseUtil;
import com.itqf.utils.AdminResponseCode;
import com.itqf.utils.AdminResponseUtil;
import com.itqf.utils.Permission;
import com.itqf.utils.PermissionUtil;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * projectName: gp_manage
 *
 * @author: 赵伟风
 * time: 2021/8/17 10:59
 * description:
 */
@Service
public class DtsAdminServiceImpl implements DtsAdminService {

    @Autowired
    private DtsAdminMapper dtsAdminMapper;

    @Autowired
    private DtsRoleService dtsRoleService;

    @Autowired
    private DtsPermissionService dtsPermissionService;


    private final  static Logger LOGGER = LoggerFactory.getLogger(DtsAdminService.class);


    /**
     * 根据用户名，查询用户信息
     *
     * @param username
     * @return
     */
    @Override
    public DtsAdmin findAdminByUserName(String username) {


        /**
         * 查询条件
         *    username = #{username}  and deleted = 0  0没有逻辑删除   1 逻辑删除
         */
        DtsAdminExample example = new DtsAdminExample();

        DtsAdminExample.Criteria criteria = example.createCriteria();

        criteria.andUsernameEqualTo(username);
        //java boolean false  --> 数据库  tinyint = 0
        criteria.andDeletedEqualTo(false);

        List<DtsAdmin> adminList = dtsAdminMapper.selectByExample(example);

        if (adminList.size()>0) {

            return adminList.get(0);
        }

        return null;
    }



    /**
     * 更新登录时间和ip地址的方法
     *
     * @param id
     * @param ip
     * @param time
     * @return
     */
    @Override
    public int updateAdminById(Integer id, String ip, Date time) {


        DtsAdmin dtsAdmin = new DtsAdmin();
        dtsAdmin.setId(id);
        dtsAdmin.setLastLoginIp(ip);
        dtsAdmin.setUpdateTime(time);

        int rows = dtsAdminMapper.updateByPrimaryKeySelective(dtsAdmin);


        return rows;
    }

    /**
     * 查询首页显示用户信息
     * 注意： 权限需要特殊格式，并且验证用户拥有并且已经完成的接口！
     *
     * @param dtsAdmin
     * @param applicationContext
     * @return
     */
    @Override
    public Map<String, Object> findAdminInfo(DtsAdmin dtsAdmin, ApplicationContext applicationContext) {


//        :{
//            "roles":["超级管理员"],  //角色
//            "name":"qianfeng", //用户名
            //                      xx:xx:xx
//                    "perms":["*","GET /admin/admin/list"], //权限 查询所有controller类中的接口
//
//            "avatar":"https://dss1.bdstatic.com/6OF1,499686101&fm=85&app=79&f=JPEG?w=121&h=75&s=81B24C32D40"  //头像
//        },

        Map<String,Object> data = new HashMap<>();

        //1.封装已有数据
        data.put("name", dtsAdmin.getUsername());
        data.put("avatar",dtsAdmin.getAvatar());

        //2.封装方便查取数据
        Integer[] roleIds = dtsAdmin.getRoleIds();

        if (roleIds == null || roleIds.length == 0){
            LOGGER.warn("[DtsAdminServiceImpl:findAdminInfo]-->[用户没有分配角色]" +
                    "-->[未进行角色分配！]-->[进行赋权]-->[username:roleIds]:{}:null",dtsAdmin.getUsername());

            return data;
        }

        List<String> roleNames = dtsRoleService.findRoleNameByRoleIds(roleIds);

        data.put("roles", roleNames);

        //3.封装复杂数据【查询，对比，赛选】

            //3.对比筛选
        //3.1 查到用户拥有的权限 - 数据库中
        List<String> permissions = dtsPermissionService.findPermissionsByRoleIds(roleIds);

        //2.查询程序已经完成的功能 map: 权限  请求方式 路径
        List<Permission> permissionList = PermissionUtil.listPermission(applicationContext, "com.itqf.controller");


        //定义一个返回的权限
        Set<String> perms = new HashSet<>();


        if (permissionList == null || permissionList.size() == 0){

            //1.真实场景  返回 空数组
            //2.开发场景  如果是超级管理员  我们返回*

            for (String permission : permissions) {
                if (permission.equalsIgnoreCase("*")) {
                    perms.add("*");
                    break;
                }
            }

            data.put("perms", perms);

            return data;
        }


        Map<String,String> hasPermissions = new HashMap<>();

        for (Permission permission : permissionList) {
            // 接口  xx:xx:xx   GET /xxx/xxx/xx
            // 已经完成的授权接口
            hasPermissions.put(permission.getRequiresPermissions().value()[0],permission.getApi());
        }

        //对比即可  数据库 和 接口完成的
        for (String permission : permissions) {

            if (permission.equalsIgnoreCase("*")) {
                perms.clear();
                perms.add("*");
                break;
            }

            if (hasPermissions.containsKey(permission)){

                perms.add(hasPermissions.get(permission));
            }
        }


        data.put("perms", perms);


        return data;
    }



    /**
     * 根据分页查询用户数据！注意分页查询！
     *
     *   分页插件
     *      1.设置分页数据  page  pageSize
     *      2.查询即可  注意：分页查询语句不能添加;
     *      3.封装分页数据即可
     *
     * @param commonsDto
     * @return
     */
    @Override
    public Map<String, Object> findAdminByPage(CommonsDto commonsDto) {

        //1.设置分页数据
        PageHelper.startPage(commonsDto.getPage(), commonsDto.getLimit());

        //2.查询数据
        DtsAdminExample  adminExample = new DtsAdminExample();
        DtsAdminExample.Criteria criteria = adminExample.createCriteria();

        if (commonsDto.getUsername() != null) {
            criteria.andUsernameLike("%"+commonsDto.getUsername()+"%");
        }

        //排序
        if (commonsDto.getOrder() != null && commonsDto.getSort() != null){

            adminExample.setOrderByClause(commonsDto.getSort()+" "+commonsDto.getOrder());
        }


        List<DtsAdmin> dtsAdminList = dtsAdminMapper.selectByExample(adminExample);

        //3.pageInfo封装

        PageInfo<DtsAdmin> pageInfo = new PageInfo<>(dtsAdminList);

        //4.返回数据封装

        Map<String,Object> data = new HashMap<>();

        data.put("total",pageInfo.getTotal());
        data.put("items", pageInfo.getList());

        return data;
    }

    /**
     * 业务方法,进行数据插入
     * 注意账号是否已经存在!
     * 注意密码长度问题!
     *
     * @param dtsAdmin
     * @return
     */
    @Override
    public Map<String, Object> insertDtsAdmin(DtsAdmin dtsAdmin) {

        //1.判断密码长度问题
        if (dtsAdmin.getPassword() == null || dtsAdmin.getPassword().length() < 6) {

            LOGGER.warn("[DtsAdminServiceImpl:insertDtsAdmin]-->[密码长度小于6!]-->[密码长度过短!]-->[密码长度大于等于6即可]-->[username:password]:{}:{}",
                    dtsAdmin.getUsername(),dtsAdmin.getPassword());

            return (Map<String, Object>) AdminResponseUtil.fail(AdminResponseCode.ADMIN_INVALID_PASSWORD);
        }

        //2.判断账号是否存在问题
        DtsAdminExample example = new DtsAdminExample();
        DtsAdminExample.Criteria criteria = example.createCriteria();
        criteria.andUsernameEqualTo(dtsAdmin.getUsername());

        long count = dtsAdminMapper.countByExample(example);

        if (count>0){

            LOGGER.warn("[DtsAdminServiceImpl:insertDtsAdmin]-->[账号已存在!]-->[账号不能重复!]-->[设置唯一账号即可]-->[username]:{}",
                    dtsAdmin.getUsername());

            return (Map<String, Object>) AdminResponseUtil.fail(AdminResponseCode.ADMIN_NAME_EXIST);
        }

        //3.插入数据并且回显主键

        //1.密码加密
        Md5Hash md5Hash = new Md5Hash(dtsAdmin.getPassword(), ShiroConstants.ADMIN_SALT,6);
        //加密后密码设置
        dtsAdmin.setPassword(md5Hash.toString());

        dtsAdmin.setAddTime(new Date());

        dtsAdmin.setDeleted(false);

        int rows = dtsAdminMapper.insertDtsAdmin(dtsAdmin);

        if (rows > 0){

            return (Map<String, Object>) ResponseUtil.ok(dtsAdmin);
        }

        return (Map<String, Object>) ResponseUtil.fail();
    }

    /**
     * 根据主键修改!
     *
     * @param dtsAdmin
     * @return
     */
    @Override
    public Object updateAdminByPrimaryKey(DtsAdmin dtsAdmin) {


        //1.判断密码
        //数据查询
        DtsAdminExample dtsAdminExample = new DtsAdminExample();
        DtsAdminExample.Criteria criteria = dtsAdminExample.createCriteria();

        criteria.andIdEqualTo(dtsAdmin.getId());
        criteria.andPasswordEqualTo(dtsAdmin.getPassword());

        long count = dtsAdminMapper.countByExample(dtsAdminExample);

        //没有查到 修改密码 123456
        if (count == 0){

            if (dtsAdmin.getPassword() == null || dtsAdmin.getPassword().length() < 6){

                LOGGER.warn("[DtsAdminServiceImpl:updateDtsAdminByPrimaryKey]-->[密码长度小于6!]-->[密码长度过短!]-->[密码长度大于等于6即可]-->[username:password]:{}:{}",
                        dtsAdmin.getUsername(),dtsAdmin.getPassword());

                return AdminResponseUtil.fail(AdminResponseCode.ADMIN_INVALID_PASSWORD);
            }

            //将密码处理成密文
            Md5Hash md5Hash = new Md5Hash(dtsAdmin.getPassword(),ShiroConstants.ADMIN_SALT,6);
            dtsAdmin.setPassword(md5Hash.toString());
        }

        //2.判断账号
        //清空之前的条件参数
        dtsAdminExample.clear();
        DtsAdminExample.Criteria exampleCriteria = dtsAdminExample.createCriteria();
        exampleCriteria.andUsernameEqualTo(dtsAdmin.getUsername());
        //非当前用户
        exampleCriteria.andIdNotEqualTo(dtsAdmin.getId());
        count = dtsAdminMapper.countByExample(dtsAdminExample);

        if (count > 0){

            LOGGER.warn("[DtsAdminServiceImpl:updateDtsAdminByPrimaryket]-->[账号已存在!]-->[账号不能重复!]-->[设置唯一账号即可]-->[username]:{}",
                    dtsAdmin.getUsername());

            return AdminResponseUtil.fail(AdminResponseCode.ADMIN_NAME_EXIST);
        }

        //3.数据修改
        dtsAdmin.setUpdateTime(new Date());

        int rows = dtsAdminMapper.updateByPrimaryKeySelective(dtsAdmin);

        if (rows>0) {

            return ResponseUtil.ok(dtsAdmin);
        }

        return ResponseUtil.fail();
    }

    /**
     * 删除用户
     *
     * @param dtsAdmin
     * @param currentUser
     * @return
     */
    @Override
    public Object deleteAdminById(DtsAdmin dtsAdmin, DtsAdmin currentUser) {

        //1.检查当前用户
        if (dtsAdmin.getId().equals(currentUser.getId())){

            return ResponseUtil.fail(-1,"不能删除正在登陆用户!");
        }

        //2.检查是不是超级管理员
        Integer[] roleIds = dtsAdmin.getRoleIds();

        if (roleIds != null || roleIds.length > 0)
        {

            List<String> permissions = dtsPermissionService.findPermissionsByRoleIds(roleIds);

            if (permissions != null && permissions.size() >0) {

                for (String permission : permissions) {

                    if (permission.equalsIgnoreCase("*")) {

                        return ResponseUtil.fail(-1, "不能删除超级管理员!");
                    }
                }

            }
        }


        //删除
        int rows = dtsAdminMapper.updateDeletedByPrimaryKey(dtsAdmin.getId(),false);

        if (rows > 0)
        {
            return  ResponseUtil.ok();
        }

        return ResponseUtil.fail();
    }
}
